package gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.util.ArrayList;

import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

import sun.java2d.loops.DrawLine;

import logic.algorithm.greedy.NearestNeighbor;
import logic.objects.Connection;
import logic.objects.ConnectionArrayList;
import logic.objects.Node;
import logic.objects.Problem;
import logic.service.PheromonService;

import java.text.DecimalFormat;

public class DiagrammPanel extends JPanel {
	private Problem problem;
	private Double coefX;
	private Double coefY;

	public DiagrammPanel(Problem prob) {
		this.problem = prob;
		setBackground(Color.white);
		setBounds(10, 10, GraphicVariables.MAX_WIDTH_Panel,
				GraphicVariables.MAX_HEIGHT_Panel);
		setBorder(new LineBorder(Color.black, 3));
		this.validate();
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		configScale(problem.getNodes());
		paintNodes(problem.getNodes(), g);
		paintConnections(problem.getConnections(), g);
		printBestSoFarSolution(PheromonService.getBestSoFarSolution(problem), g);
		String bestValue;
		DecimalFormat format = new java.text.DecimalFormat("#.00");
		if (problem.getBestTourSoFarValue() == null) {
			bestValue = format.format(PheromonService
					.getNearestNeighborShortedTourValue(problem));
		} else if (problem.getBestTourSoFarValue().equals(Double.MAX_VALUE)) {
			bestValue = "-";
		} else
			bestValue = format.format(problem.getBestTourSoFarValue());
		paintText("Kosten der besten bisher gefundenen Tour: " + bestValue, g,
				50);
	}

	private void printBestSoFarSolution(ArrayList<Node> bestTourSoFar,
			Graphics g) {
		if (bestTourSoFar != null) {
			Graphics2D g2 = (Graphics2D) g;
			g2.setStroke(new BasicStroke(3));
			g2.setColor(new Color(0, 0, 255, 100));

			for (int i = 0; i < bestTourSoFar.size() - 1; i++) {
				Node node1 = bestTourSoFar.get(i);
				Node node2 = bestTourSoFar.get(i + 1);
				int x1 = (int) (node1.getX() * coefX);
				int y1 = (int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
						* node1.getY());
				int x2 = (int) (node2.getX() * coefX);
				int y2 = (int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
						* node2.getY());
				g2.drawLine(x1, y1, x2, y2);
			}
			Node node1 = bestTourSoFar.get(0);
			Node node2 = bestTourSoFar.get(bestTourSoFar.size() - 1);
			int x1 = (int) (node1.getX() * coefX);
			int y1 = (int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
					* node1.getY());
			int x2 = (int) (node2.getX() * coefX);
			int y2 = (int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
					* node2.getY());
			g2.drawLine(x1, y1, x2, y2);
		}
	}

	public void paintNodes(ArrayList<Node> nodes, Graphics g) {
		for (Node node : nodes) {
			g.fillRect(
					(int) (node.getX() * coefX) - 4,
					(int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
							* node.getY()) - 4, 8, 8);
		}
	}

	public void paintConnections(ConnectionArrayList connections, Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		g2.setStroke(new BasicStroke(2));
		PheromonService.updateMaxPheromon(problem);
		ArrayList<Connection> list;
		for (int i = 0; i < connections.getSizeX(); i++) {
			for (int j = 0; j < connections.getSizeY(); j++) {
				if (i != j) {
					Connection con = (connections.get(i, j));
					if ((con != null) && !(con.isDummy())) {

						Node node1 = con.getNode1();
						Node node2 = con.getNode2();
						int x1 = (int) (node1.getX() * coefX);
						int y1 = (int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
								* node1.getY());
						int x2 = (int) (node2.getX() * coefX);
						int y2 = (int) (GraphicVariables.MAX_HEIGHT_Panel - coefY
								* node2.getY());
						if (problem.color)
							g2.setColor(new Color(255, 0, 0, PheromonService
									.getPheromon(con, problem)));
						else
							g2.setColor(new Color(0, 255, 0, PheromonService
									.getPheromon(con, problem)));

						g2.drawLine(x1, y1, x2, y2);
					}

				}
			}
		}
	}

	private void configScale(ArrayList<Node> nodes) {
		Integer maxX = 0;
		Integer maxY = 0;
		for (Node node : nodes) {
			maxX = node.getX() > maxX ? node.getX() : maxX;
			maxY = node.getY() > maxY ? node.getY() : maxY;
		}
		coefX = (double) (GraphicVariables.MAX_WIDTH_Panel - 30)
				/ (double) (maxX);
		coefY = (double) (GraphicVariables.MAX_HEIGHT_Panel - 30)
				/ (double) (maxY);
	}

	private void paintText(String str, Graphics g, int x) {
		g.setColor(new Color(0, 0, 0, 100));

		g.drawString(str, 20, 20);
	}

}
